package com.cn.demo.config;

import com.cn.demo.entity.SeckillGoods;
import com.cn.demo.util.RequestResultCode;
import org.redisson.api.RMapCache;
import org.redisson.api.RQueue;
import org.redisson.api.RedissonClient;
import org.redisson.api.map.event.EntryEvent;
import org.redisson.api.map.event.EntryExpiredListener;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import java.util.concurrent.TimeUnit;

/**
 * 队列工厂，通过该工厂生产秒杀队列，统一进行管理
 *
 * @author wangjf
 * @version 1.0
 * @createDate 2019/11/21 10:25
 * @projectName demo
 */
@Component
public class SeckillQueueFactory implements InitializingBean {
    private final static Long SECKILL_TTL = 10L;

    @Autowired
    private RedissonClient redisson;
    //秒杀队列的名字和活动状态,状态0代表未开始，1代表进行中，2代表活动结束，3代表秒杀取消
    private RMapCache<String, Integer> seckillQueueMap;


    @Override
    public void afterPropertiesSet() throws Exception {

        if (seckillQueueMap == null) {

            seckillQueueMap = redisson.getMapCache("seckillQueueMap");
            //过期时判断秒杀是否结束，并且回填数据至数据库
            //TODO
            seckillQueueMap.addListener(new EntryExpiredListener<String, Integer>() {
                @Override
                public void onExpired(EntryEvent<String, Integer> event) {

                }
            });
        }
        Assert.notNull(seckillQueueMap, "秒杀队列工厂初始化失败, seckillQueueMap is null");
    }


    /**
     * 获取活动状态
     *
     * @param queueName
     * @return int
     * @author: wangjf
     * @createTime: 2019/11/21 13:56
     */
    public int getStatus(String queueName) {

        Integer integer = seckillQueueMap.get(queueName);
        if (integer == null) {
            return RequestResultCode.SECKILL_NOT_EXIST.getErrorCode();
        }
        return integer;
    }


    /**
     * 获取一个初始化队列
     *
     * @param
     * @return org.redisson.api.RQueue<com.cn.demo.entity.SeckillGoods>
     * @author: wangjf
     * @createTime: 2019/11/21 10:43
     */
    public RQueue<SeckillGoods> getQueue() {

        String queueName = "sq" + System.currentTimeMillis();
        seckillQueueMap.put(queueName, RequestResultCode.SECKILL_READY.getErrorCode(), SECKILL_TTL, TimeUnit.DAYS);
        RQueue<SeckillGoods> queue = redisson.getQueue(queueName);
        return queue;
    }

    /**
     * 获取活动中的队列
     *
     * @param queueName
     * @return org.redisson.api.RQueue<com.cn.demo.entity.SeckillGoods>
     * @author: wangjf
     * @createTime: 2019/11/21 14:41
     */
    public RQueue<SeckillGoods> getQueue(String queueName) {

        RQueue<SeckillGoods> queue = redisson.getQueue(queueName);
        return queue;
    }

    /**
     * 未启动的活动可以启动，这里需要保证操作的线程安全
     *
     * @param queueName
     * @return void
     * @author: wangjf
     * @createTime: 2019/11/21 11:09
     */
    public synchronized void startQueue(String queueName) {
        seckillQueueMap.put(queueName, RequestResultCode.SECKILL_DOING.getErrorCode(), SECKILL_TTL, TimeUnit.HOURS);
    }

    /**
     * 结束队列
     *
     * @param queueName
     * @return void
     * @author: wangjf
     * @createTime: 2019/11/21 11:15
     */
    public synchronized void endQueue(String queueName) {

        seckillQueueMap.put(queueName, RequestResultCode.SECKILL_FINISH.getErrorCode(), SECKILL_TTL, TimeUnit.MINUTES);
    }

    /**
     * 取消队列
     *
     * @param queueName
     * @return void
     * @author: wangjf
     * @createTime: 2019/11/21 11:15
     */
    public synchronized void cancelQueue(String queueName) {

        seckillQueueMap.put(queueName, RequestResultCode.SECKILL_CANCEL.getErrorCode(), SECKILL_TTL, TimeUnit.MINUTES);
    }

}
